<template>
  <div class="draggable-table-container">
    <a-space style="width: 100%; justify-content: flex-end; margin-bottom: 15px">
      <a-button type="primary" size="medium" @click="handleCreateFormField">
        <template #icon><PlusOutlined/></template>添加
      </a-button>
      <a-button size="medium"  @click="handleClearFormField">
        <template #icon><DeleteOutlined/></template>
      </a-button>
    </a-space>
    <a-table
      :columns="columns"
      :data-source="props.field"
      :pagination="false"
      size="small"
      rowKey="uuid"
      bordered
      :expand-column-width="55"
    >
      <!-- 额外的展开行 -->
      <template #expandedRowRender="{ record }">
        {{ record.label }}
      </template>
      <!-- 自定义展开列表头 -->
      <template #expandColumnTitle>展开</template>
      <!-- 个性化单元格 -->
      <template #bodyCell="{ column, text, record, index }">

        <template v-if="['label'].includes(column.dataIndex)">
          <a-input
              v-model:value="record.label"
              @change="(val) => handleLabelChange(val, record, index)"
          />
        </template>

        <template v-else-if="['value'].includes(column.dataIndex)">
<!--          <a-input v-model:value="record.value"/>-->
          {{ record.value}}
        </template>

        <template v-else-if="['required'].includes(column.dataIndex)">
          <a-checkbox v-model:checked="record.required"></a-checkbox>
        </template>

        <template v-else-if="['type'].includes(column.dataIndex)">
          <a-select
            v-model:value="record.type"
            :options="fieldTypeOptions"
            style="width: 100%"
          />
        </template>

        <template v-else-if="column.dataIndex === 'operate'">
          <a-button type="link" size="small" @click="handleDeleteFormField(record)">删除</a-button>
        </template>
      </template>
    </a-table>
  </div>
</template>

<script setup>
	import { ref, defineProps, defineEmits } from 'vue';

	import {
    HolderOutlined,
    PlusOutlined,
    DeleteOutlined
  } from '@ant-design/icons-vue'

  import { transformLabelToStr, guid } from '@/build/utils/index.js';

  import Components from '@/build/config/component/index.js'

	const props = defineProps({
    field: {
			type: Array,
			required: true,
		}
	})

  const emits = defineEmits(['update:field'])

	const formComponentOpts = Object.entries(Components).map(([key, value]) => ({
    label: value.componentLabel,
    value: value.componentKey
  }))

	const fieldTypeOptions = ref(formComponentOpts)

	const sourceObj = ref({})
	const targetObj = ref({})

	let sourceIndex
	let targetIndex

	const columns = [
		// { title: '', dataIndex: 'drag', width: 30 },
		{ title: '名称', dataIndex: 'label' },
    { title: '字段', dataIndex: 'value', width: 130 },
		{ title: '类型', dataIndex: 'type', width: 130 },
    { title: '必填', dataIndex: 'required', align: 'center', width: 60 },
    { title: '操作', dataIndex: 'operate', align: 'center', width: 60 },
	]

  const handleCreateFormField = () => {
    const field = [...props.field]

    const generateLabel = getAvailableLabel()

    const existStr = props.field.map(item => item.value)

    const instance = ref({
      uuid: guid(),
      label: generateLabel,
      value: transformLabelToStr(generateLabel, existStr),
      type: 'Input',
      required: false
    })

    field.push(instance.value)

    console.log(field)

    emits('update:field', field)
  }

  const handleClearFormField = () => {
    emits('update:field', [])
  }

  const handleDeleteFormField = (record) => {
    const field = props.field

    emits('update:field', field.filter(item => item.uuid !== record.uuid))
  }

  const handleLabelChange = (val, record, index) => {
    console.log(val, record, index)

    const field = [...props.field]

    const existStr = field
        .filter(item => item.uuid !== record.uuid)
        .map(item => item.value)

    field.forEach(item => {
      if (item.uuid === record.uuid) {
        item.value  = transformLabelToStr(record.label, existStr)
      }
    })

    emits('update:field', field)
  }

  const getAvailableLabel = () => {
    const baseName = '字段名称'
    const existLabel = props.field.map(item => item.label)

    let finalName = baseName
    let suffix = 0

    while (existLabel.includes(finalName)) {
      suffix++
      finalName = `${baseName}${suffix}`
    }

    return finalName
  }

	const customRow = (record, index) => {
		const style = {
			cursor: 'pointer'
		}
		// 鼠标移入
		const onMouseenter = event => {
			// 兼容IE
			const ev = event || window.event
			ev.target.draggable = true
		}

		const onDragstart = event => {
			const ev = event || window.event
			ev.stopPropagation()
			// 得到源目标数据
			sourceObj.value = record
			sourceIndex = index
		}

		const onDragover = event => {
			const ev = event || window.event
			ev.preventDefault()
			ev.dataTransfer.dropEffect = 'move'
			ev.dataTransfer.effectAllowed = 'move'
			targetIndex = index
		}

		const onDragenter = event => {
			const ev = event || window.event
			ev.preventDefault()
			const list = document.getElementsByClassName('ant-table-row')
			const node = document.getElementsByClassName('target')
			if (node.length) {
				node[0].classList.remove('target')
			}
			list[index].classList.add('target')
		}
		// 鼠标松开
		const onDrop = event => {
			const ev = event || window.event
			ev.stopPropagation()
			targetObj.value = record
			targetIndex = index
			const node = document.getElementsByClassName('target')
			if (node.length) {
				node[0].classList.remove('target')
			}
			if (targetIndex === sourceIndex) return

			props.field.splice(sourceIndex, 1)
			props.field.splice(targetIndex, 0, sourceObj.value)
		}
		return {
			style,
			onMouseenter,
			onDragstart,
			onDragover,
			onDrop,
			onDragenter
		}
	}
</script>

<style scoped lang="scss">
  .drag-handle {
    cursor: grab;
    font-size: 12px;
    display: inline-block;
  }

  .draggable-table-container {

  }

  :deep(.ant-table-cell) {
    padding: 12px !important;
  }
</style>
